package ext.acae2.change.workflow;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import wt.change2.ChangeHelper2;
import wt.change2.WTChangeOrder2;
import wt.content.ApplicationData;
import wt.content.ContentHelper;
import wt.content.ContentHolder;
import wt.content.ContentItem;
import wt.content.ContentRoleType;
import wt.content.ContentServerHelper;
import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.WTObject;
import wt.folder.Folder;
import wt.folder.FolderHelper;
import wt.iba.value.IBAHolder;
import wt.inf.container.WTContainerRef;
import wt.ixb.clientAccess.StandardIXBService;
import wt.ixb.publicforhandlers.IxbHndHelper;
import wt.lifecycle.LifeCycleException;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.State;
import wt.log4j.LogR;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.pom.Transaction;
import wt.project.Role;
import wt.representation.Representable;
import wt.representation.Representation;
import wt.representation.RepresentationHelper;
import wt.representation.RepresentationType;
import wt.session.SessionHelper;
import wt.team.Team;
import wt.team.TeamHelper;
import wt.team.TeamReference;
import wt.util.CollationKeyFactory;
import wt.util.SortedEnumeration;
import wt.util.WTException;
import wt.vc.VersionControlHelper;
import wt.viewmarkup.DerivedImage;
import wt.workflow.engine.ProcessData;
import wt.workflow.engine.WfEngineHelper;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfState;

import com.ptc.core.meta.common.TypeIdentifierHelper;
import com.ptc.windchill.enterprise.team.server.TeamCCHelper;

import ext.acae.constants.AcaeConstants;
import ext.acae.signature.NfSignPDF;
import ext.acae.signature.NfSignature;
import ext.acae.signature.NfSignatureProperties;
import ext.acae.util.IBAHelper;
import ext.acae.util.NfDataDispatchInfoHelper;
import ext.acae.workflow.service.NfWorkflowHelper;
import ext.acae2.ACAEConstants;
import ext.acae2.change.helper.ECNHelper;
import ext.acae2.utilities.core.CSCIBA;
import ext.acae2.utilities.principal.CSCPrincipal;

/**
 * @desription ECN workflow helper
 * @author cnie
 * @date 2013-5-15 下午2:18:33
 */
public class ECNWorkflowHelper {

	private static final Logger LOGGER = LogR.getLogger(ECNWorkflowHelper.class
			.getName());

	/**
	 * @description check is has representation
	 * @author cnie
	 * @date 2013-5-20 上午10:12:39
	 * @version 1.0
	 * @param p
	 * @return
	 * @throws WTException
	 */
	public static boolean hasDefaultRepresentation(Persistable p)
			throws WTException {
		Representation represention = RepresentationHelper.service
				.getDefaultRepresentation((Representable) p);
		if (represention != null
				&& represention.getRepresentationType().equals(
						RepresentationType.PRODUCT_VIEW))
			return true;
		else
			return false;
	}

	/**
	 * 
	 * @description is correct representation
	 * @author cnie
	 * @date 2013-5-20 上午10:13:14
	 * @version 1.0
	 * @param p
	 * @return
	 * @throws WTException
	 */
	public static boolean correctRespresentation(Persistable p)
			throws WTException {
		Representation representation = RepresentationHelper.service
				.getDefaultRepresentation((Representable) p);
		if (representation == null)
			return false;
		if (!(representation instanceof DerivedImage))
			return false;
		DerivedImage di = (DerivedImage) representation;
		ObjectReference or = di.getDerivedFromReference();
		Persistable pp = or.getObject();
		if (PersistenceHelper.getObjectIdentifier(p).equals(
				PersistenceHelper.getObjectIdentifier(pp)))
			return true;
		else
			return false;
	}

	/**
	 * 
	 * @description check ecn Affected item have Visualization
	 * @author cnie
	 * @date 2013-5-15 下午2:20:24
	 * @version 1.0
	 * @param self
	 * @param obj
	 * @return
	 */
	public static String checkDocHaveVisualization(ObjectReference self,
			Object pbo) {
		String result = "Y";
		try {
			if (pbo instanceof WTChangeOrder2) {
				WTChangeOrder2 ecn = (WTChangeOrder2) pbo;
				ArrayList<WTObject> wtobjects = ECNHelper
						.getChangeResultingItem(ecn);
				WTObject wtobject = wtobjects.get(0);
				if (wtobject instanceof WTDocument) {
					WTDocument doc = (WTDocument) wtobject;
					if (!hasDefaultRepresentation(doc))
						result = "N";
					if (!correctRespresentation(doc))
						result = "N";
				}
			}
		} catch (WTException wte) {
			wte.printStackTrace();
		}
		return result;
	}

	/**
	 * 
	 * @description check workflow role have set participants
	 * @author cnie
	 * @date 2013-5-16 上午10:49:10
	 * @version 1.0
	 * @return
	 */
	public static boolean isRoleSetParticipantsInWorkflow(
			Object obj, String roleStr) {
		boolean isRoleSetUserFlag = true;
		try {
			WfProcess process = (WfProcess) obj;
			Role role = Role.toRole(roleStr);
			Team procTeam = (Team) process.getTeamId().getObject();
			Map rolePrincipalListMap = TeamHelper.service
					.findAllParticipantsByRole(procTeam);
			List userList = (List) rolePrincipalListMap.get(role);
			if (userList == null || userList.size() == 0)
				isRoleSetUserFlag = false;
		} catch (WTException e) {
			e.printStackTrace();
		}

		return isRoleSetUserFlag;

	}
	
	/**
	 * 判断角色是否存在
	 * @description TODO
	 * @author cnie
	 * @date 2013-6-8 下午5:30:36
	 * @version 1.0
	 * @param self
	 * @param rolestr
	 * @return
	 */
	public static boolean isRoleSetParticipantsInWorkflow(ObjectReference self, String rolestr) {
		
		return NfWorkflowHelper.isRoleSetParticipantsInWorkflow(self, rolestr);  
	}

	/**
	 * 
	 * @description skip by document Type for danganqueren
	 * @author cnie
	 * @date 2013-5-16 上午11:01:28
	 * @version 1.0
	 * @param self
	 * @param obj
	 * @return
	 */
	public static boolean isSkipDocumentType(ObjectReference self, Object pbo) {
		boolean isSkipDocumentType = true;
		if (pbo instanceof WTChangeOrder2) {
			WTChangeOrder2 ecn = (WTChangeOrder2) pbo;
			ArrayList<WTObject> resultingItems = ECNHelper
					.getChangeResultingItem(ecn);

			CSCIBA cscIba = new CSCIBA((IBAHolder) resultingItems.get(0));
			String docType = cscIba
					.getIBAValue(ACAEConstants.ACAE2_IBA_TECHDOC_TYPE);
			if (!ACAEConstants.ACAE2_TECH_DOC_TYPE_VALUE.equals(docType))
				isSkipDocumentType = false;

		}
		return isSkipDocumentType;
	}

	/**
	 * 
	 * @description move ECN affected Item to other folder
	 * @author cnie
	 * @date 2013-5-16 上午11:30:10
	 * @version 1.0
	 * @param self
	 * @param obj
	 */
	public static void moveAfftedItemAfterApprove(ObjectReference self,
			Object pbo) {
		try {
			if (!(pbo instanceof WTChangeOrder2))
				return;
			WTChangeOrder2 ecn = (WTChangeOrder2) pbo;
			ArrayList<WTObject> docs = ECNHelper.getChangeResultingItem(ecn);
			for (WTObject wtObj : docs) {
				WTDocument doc = (WTDocument) wtObj;
				WTContainerRef containerRef = doc.getContainerReference();
				CSCIBA cscIba = new CSCIBA(doc);
				String secretLevel = cscIba
						.getIBAValue(ACAEConstants.ACAE2_IBA_SECRETLEVEL);
				String folderPath = FolderHelper.getFolder(doc).getFolderPath();
				LOGGER.debug("---folderPath-->" + folderPath);
				String rootPath;
				if (folderPath.endsWith(ACAEConstants.ACAE2_FOLDER_A)
						|| folderPath.endsWith(ACAEConstants.ACAE2_FOLDER_B))
					rootPath = folderPath.substring(0,
							folderPath.lastIndexOf("/"));
				else
					rootPath = folderPath;
				String changePath = rootPath;
				if (ACAEConstants.ACAE2_PUTONGSHANGMI_SECRET_LEVEL_VALUE
						.equals(secretLevel))
					changePath = rootPath + "/" + ACAEConstants.ACAE2_FOLDER_B;
				else if (ACAEConstants.ACAE2_HEXINSHANGMI_SECRET_LEVEL_VALUE
						.equals(secretLevel))
					changePath = rootPath + "/" + ACAEConstants.ACAE2_FOLDER_A;
				if (!folderPath.equals(changePath)) {
					LOGGER.debug("---changePath-->" + changePath);
					Folder folder = IxbHndHelper.getFolder(changePath,
							containerRef.getContainer()
									.getDefaultDomainReference(), containerRef);
					List<WTDocument> documents =allVersionOf(doc);
					for(WTDocument document:documents)
						FolderHelper.service.changeFolder(document, folder);
				}
			}
		} catch (WTException wte) {
			wte.printStackTrace();
		}
	}
	
	public static List<WTDocument> allVersionOf(WTDocument doc) throws WTException{
		List<WTDocument> docs = new ArrayList<WTDocument>();
		QueryResult qr = VersionControlHelper.service.allVersionsOf(doc.getMaster());
		while(qr.hasMoreElements()){
			WTDocument document = (WTDocument) qr.nextElement();
			docs.add(0,(WTDocument) VersionControlHelper.getLatestIteration(document));
		}
		return docs;
	}

	/**
	 * 
	 * @description send email to ECN affected item owner
	 * @author cnie
	 * @date 2013-5-16 上午11:33:31
	 * @version 1.0
	 * @param self
	 * @param obj
	 */
	public static void sendToAffectedOwner(ObjectReference self, Object pbo) {

	}

	/**
	 * 
	 * @description generate final Printable Attachment
	 * @author cnie
	 * @date 2013-5-16 下午12:02:46
	 * @version 1.0
	 * @param self
	 * @param pbo
	 */
	public static void generatePrintableAttachmentStepTwo(ObjectReference self,
			Object pbo) {

	}

	/**
	 * 
	 * @description dispatch department is internal
	 * @author cnie
	 * @date 2013-5-16 下午12:49:41
	 * @version 1.0
	 */
	public static boolean hasExternalDispatch(String needSendDept) {
		return NfWorkflowHelper.hasExternalDispatch(needSendDept); //调用一期的代码

	}

	/***
	 * 
	 * @description set receiver
	 * @author cnie
	 * @date 2013-5-16 下午12:56:00
	 * @version 1.0
	 * @param self
	 * @param pbo
	 */
	public static void setReceivers(ObjectReference self, Object pbo, String departmentsStr) {
		
		try {
			if (departmentsStr==null || departmentsStr.equals(""))
				return;
			String[] departments=departmentsStr.split(",");
			List<WTUser> userList=new ArrayList<WTUser>();
			for (int k=0; k<departments.length; k++) {
				List<String> list=NfDataDispatchInfoHelper.getNfDataDispatchInfoHelper().getReceivers(departments[k]);
				if (list.size()<=0) {
					WTUser user=(WTUser) SessionHelper.manager.getAdministrator();
					if (!userList.contains(user))
						userList.add(user);
				} else {
					for (String u:list) {
						WTUser user=CSCPrincipal.getUserByName(u);
						if(user == null)
							user = CSCPrincipal.getUserByFullName(u);
						if (user==null)
							user=(WTUser) SessionHelper.manager.getAdministrator();
						if (!userList.contains(user))
							userList.add(user);
					}
				}
			}
			if (userList.size()>0)
				addTeamPrincipals(pbo, Role.toRole(ACAEConstants.ROLE_RECEIVER), userList);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//NfWorkflowHelper.setReceivers(pbo, departmentsStr);//调用一期的代码

	}
	
	public static void addTeamPrincipals(Object obj, Role role, List<WTUser> userList) {
		try {
			Team team=(Team)TeamCCHelper.getTeamFromObject((LifeCycleManaged)obj);
			if (team==null) {
    			LOGGER.debug("Not found Object Team.");
    			return;
    		}
			boolean added=false;
			team=(Team)PersistenceHelper.manager.refresh(team);
			Vector objRoles=TeamHelper.service.findRoles(team);
			HashMap roleMap=TeamHelper.service.findAllParticipantsByRole(team);
			if (objRoles.contains(role)) {
				ArrayList principalList=(ArrayList)roleMap.get(role);
				for (WTUser user:userList) {
					boolean exists=false;
					for (int j=0; j<principalList.size(); j++) {
						WTPrincipal principal = (WTPrincipal) ((WTPrincipalReference)principalList.get(j)).getPrincipal();
						if (principal.equals(user)) {
							exists=true;
							break;
						}
					}
					if (!exists) {
						team.addPrincipal(role, user);
						added=true;
					}
				}
			} else {
				for (WTUser user:userList) {
					team.addPrincipal(role, user);
				}
				added=true;
			}
			if (added) {
				TeamReference teamreference = TeamReference.newTeamReference(team);
				TeamHelper.service.augmentRoles((LifeCycleManaged)obj, teamreference);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	/***
	 * 
	 * @description 
	 *  流程开始是设置产生对象的发放状态
	 * @author cnie
	 * @date 2013-5-23 下午5:25:19
	 * @version 1.0
	 * @param self
	 * @param pbo
	 * @throws WTException 
	 */
	public static void doWorkBeforeReviewProcess(ObjectReference self,Object pbo) throws WTException{
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			String ecntype = TypeIdentifierHelper.getType(ecn).toExternalForm();
			if(ecntype.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
				WTDocument doc = (WTDocument) ECNHelper.getChangeResultingItem(ecn).get(0);
				CSCIBA.setIBAStringValue(doc, ACAEConstants.ACAE2_IBA_DISPATCH_STATUS, ACAEConstants.ACAE2_VALUE_NOT_DISPATCH);
			}
			
		}
	}
	
	/**
	 * 
	 * @description 开始发放
	 * @author cnie
	 * @date 2013-5-23 下午5:47:31
	 * @version 1.0
	 * @param self
	 * @param pbo
	 * @throws WTException
	 */
	public static void beginDispatch(ObjectReference self,Object pbo) throws WTException{
//		if(pbo instanceof WTChangeOrder2){
//			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
//			String ecntype = TypeIdentifierHelper.getType(ecn).toExternalForm();
//			if(ecntype.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
//				WTDocument doc = (WTDocument) ECNHelper.getChangeResultingItem(ecn).get(0);
//				CSCIBA.setIBAStringValue(doc, ACAEConstants.ACAE2_IBA_DISPATCH_STATUS, ACAEConstants.ACAE2_VALUE_DISPATCHING);
//			}
//			
//		}
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			String ecntype = TypeIdentifierHelper.getType(ecn).toExternalForm();
			if(ecntype.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
				ArrayList<WTObject> wtobjs = ECNHelper.getChangeResultingItem(ecn);
				for(WTObject wtobj:wtobjs){
					if(wtobj instanceof IBAHolder)
						NfWorkflowHelper.beginDoDispatch(self, wtobj);//调用一期的代码
				}
			}
		}
		
	}
	
	/**
	 * 
	 * @description 
	 * 设置发放状态完成
	 * @author cnie
	 * @date 2013-5-23 下午5:54:33
	 * @version 1.0
	 * @param self
	 * @param pbo
	 * @throws WTException
	 */
	public static void endDispatch(ObjectReference self,Object pbo) throws WTException{
//		if(pbo instanceof WTChangeOrder2){
//			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
//			String ecntype = TypeIdentifierHelper.getType(ecn).toExternalForm();
//			if(ecntype.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
//				WTDocument doc = (WTDocument) ECNHelper.getChangeResultingItem(ecn).get(0);
//				CSCIBA.setIBAStringValue(doc, ACAEConstants.ACAE2_IBA_DISPATCH_STATUS, ACAEConstants.ACAE2_VALUE_DISPATCHED);
//			}
//			
//		}
		
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			String ecntype = TypeIdentifierHelper.getType(ecn).toExternalForm();
			if(ecntype.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
				ArrayList<WTObject> wtobjs = ECNHelper.getChangeResultingItem(ecn);
				for(WTObject wtobj:wtobjs){
					if(wtobj instanceof IBAHolder)
						NfWorkflowHelper.endDoDispatch(self, wtobj);//调用一期的代码
				}
			}
		}
	}
	
	

	
//	public static void checkRoleParticipant(ObjectReference self, Object pbo)
//			throws WTException {
//		WfProcess process = null;
//		Object obj =self.getObject();
//		
//		if (obj instanceof WfProcess) {
//			process = (WfProcess) obj;
//		} else if (obj instanceof WfActivity) {
//			WfActivity activity = (WfActivity) obj;
//			WfContainer wfcont = (WfContainer) activity.getParentProcessRef()
//					.getObject();
//			if (wfcont instanceof WfBlock) {
//				WfBlock wb = (WfBlock) wfcont;
//				wfcont = wb.getParentProcess();
//			}
//			process = (WfProcess) wfcont;
//		}
//
//		Team processTeam = (Team) process.getTeamId().getObject();
//
//		@SuppressWarnings("unchecked")
//		Map<Role, List<WTPrincipalReference>> rolePrincipalMap = processTeam
//				.getRolePrincipalMap();
//		for (java.util.Iterator<Role> roles = rolePrincipalMap.keySet()
//				.iterator(); roles.hasNext();) {
//			Role role = roles.next();
//			if (Role.toRole(ACAEConstants.ROLE_CORRECTOR).equals(role)
//					|| Role.toRole(ACAEConstants.ROLE_REVIEWER)
//							.equals(role)
//					|| Role.toRole(ACAEConstants.ROLE_CRITERIAREVIEWER).equals(role)
//					|| Role.toRole(ACAEConstants.ROLE_APPROVER)
//							.equals(role)) {
//				List<WTPrincipalReference> wtrprincipalrefs = rolePrincipalMap
//						.get(role);
//				if (wtrprincipalrefs == null || wtrprincipalrefs.size() == 0) {
//					throw new WTException("流程角色："
//							+ role.getDisplay(Locale.CHINA) + "没有设置参与者");
//				}
//				Vector<WTUser> users = new Vector<WTUser>();
//				for (WTPrincipalReference wtrprincipalref : wtrprincipalrefs) {
//					WTPrincipal principal = wtrprincipalref.getPrincipal();
//					if (principal instanceof WTUser) {
//						WTUser user = (WTUser) principal;
//						users.add(user);
//					} else if (principal instanceof WTGroup) {
//						WTGroup group = (WTGroup) principal;
//						Vector userVec = new Vector();
//						userVec = CSCPrincipal.getGroupMemberUsers(group,
//								userVec);
//						users.addAll(userVec);
//					}
//				}
//
//				if (users == null || users.size() == 0) {
//					throw new WTException("流程角色："
//							+ role.getDisplay(Locale.CHINA) + "没有设置参与者");
//				}
//
//				if (Role.toRole(ACAEConstants.ROLE_CRITERIAREVIEWER).equals(role)) {
//
//					WTGroup bzGroup = CSCPrincipal
//							.getGroupByName(ACAEConstants.ACAE2_GROUP_BIAOZHUN);
//					Vector userVec = new Vector();
//					userVec = CSCPrincipal
//							.getGroupMemberUsers(bzGroup, userVec);
//					for (WTUser user : users) {
//						if (!userVec.contains(user)) {
//							throw new WTException("流程角色："
//									+ role.getDisplay(Locale.CHINA) + "中的："
//									+ user.getFullName()
//									+ ACAEConstants.ACAE_GROUP_BIAOZHUN);
//						}
//					}
//				}
//			}
//		}
//	}
	
	
	public static void generatePrintableAttachmentStepOne(ObjectReference self, Object obj) {
		LOGGER.debug("======= Start generatePrintableAttachmentStepOne");
		File repFile=null;
		File tmpFile=null;
		try{
			NfSignatureProperties props=NfSignatureProperties.getNfSignatureProperties(true);
			if(obj instanceof WTChangeOrder2){
				WTChangeOrder2 ecn = (WTChangeOrder2)obj;
				String ecntype = TypeIdentifierHelper.getType(ecn).toExternalForm();
				if(ecntype.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
					WTDocument doc = (WTDocument) ECNHelper.getChangeResultingItem(ecn).get(0);
					LOGGER.debug("====doc=== number: "+doc.getNumber());
					ApplicationData signfrom=null;
					Representation representation = RepresentationHelper.service.getDefaultRepresentation(doc);
					if (representation != null) {//
						LOGGER.debug("====== representation not null!");
		            	representation = (Representation)ContentHelper.service.getContents(representation);
		                if (representation != null) {
		                	Vector contents = ContentHelper.getContentList(representation);
		                	System.out.println("====== contents size: " + contents.size());
		                    for (Object content : contents) {
		                    	ContentItem contentItem = (ContentItem) content;
		                    	LOGGER.debug("====== contentItem: " + contentItem.getClass().getName());
		                    	if (!(contentItem instanceof ApplicationData)) {
		                        	continue;
		                        }
		                        ApplicationData ad = (ApplicationData) contentItem;
		                        String fileName = ad.getFileName();
		                        System.out.println("====== fileName: " + fileName);
		                        if (fileName.toUpperCase().endsWith(".PDF")){
		                        	signfrom=ad;
		                        	break;
		                        }
		                    }
		                }
		                if (signfrom==null) {
		                	LOGGER.debug("Not found representation in PDF format");
		                	return;
		                }
		                LOGGER.debug("====== signfrom: " + signfrom.getFileName());
		                repFile=StandardIXBService.getSaveFileOnServer();
		                LOGGER.debug("====== repFile: " + repFile.getName() + "\t" + repFile.getCanonicalPath());
		                ContentServerHelper.service.writeContentStream(signfrom, repFile.getCanonicalPath());
		    			if (!repFile.exists()) {
		    				 LOGGER.debug("Output Representation File error!");
		    				return;
		    			}
		    			HashMap info=NfSignature.getBasicInfo(doc); 
		    			System.out.println("====== info size: " + info.size());
		    			for (Object key : info.keySet()) {
		    				System.out.println("KEY: " + key);
		    				System.out.println("VALUE: " + info.get(key));
		    			}
		    			tmpFile=StandardIXBService.getSaveFileOnServer();
		    			LOGGER.debug("====== tmpFile: " + tmpFile.getName());
		    			LOGGER.debug("Write to :"+ tmpFile.getCanonicalPath());
		    			NfSignPDF signPDF=new NfSignPDF(repFile.getCanonicalPath(), tmpFile.getCanonicalPath(), info);
		    			signPDF.sign(0);
		    			System.out.println("====== sign done");
		    			if (!tmpFile.exists()) {
		    				LOGGER.debug("Printable file not generated!");
		    				return;
		    			}
		    			
		    			deleteDocumentPrintAttachment(obj);
		    			LOGGER.debug("====== delete done");
		    			generatePrintableAttachment(doc, tmpFile);
		    			LOGGER.debug("====== generate done");
		    			CSCIBA.setIBAStringValue(doc, ACAEConstants.ACAE2_IBA_TOTAL_PAGE, String.valueOf(signPDF.getTotalpage()));
		            }
				}
				
			}
			
		}catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	/**
	 * 
	 * @description 
	 * get resulting item secretLevel
	 * @author cnie
	 * @date 2013-5-23 下午4:38:16
	 * @version 1.0
	 * @param pbo
	 * @return
	 * @throws WTException
	 */
	public static String getPboResultingItemSecretLevel(Object pbo) throws WTException{
		String secretLevel = null;
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			String ecnType = TypeIdentifierHelper.getType(ecn).toExternalForm();
			if(ecnType.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
				WTDocument doc = (WTDocument) ECNHelper.getChangeResultingItem(ecn).get(0);
				secretLevel = IBAHelper.getIBAStringValue(doc, ACAEConstants.ACAE2_IBA_SECRETLEVEL);
				if(StringUtils.isBlank(secretLevel))
					secretLevel=AcaeConstants.VALUE_NEIBUXINXI;
			}
		}
		return secretLevel;
		
	}
	
	
	public static void setPboResultItemSecretLevel(Object pbo,String secretLevel) throws WTException{
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			String ecnType = TypeIdentifierHelper.getType(ecn).toExternalForm();
			if(ecnType.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
				WTDocument doc = (WTDocument) ECNHelper.getChangeResultingItem(ecn).get(0);
				CSCIBA.setIBAStringValue(doc, ACAEConstants.ACAE2_IBA_SECRETLEVEL, secretLevel);
			}
		}
	}
	
	public static void deleteDocumentPrintAttachment(Object pbo) {
		try {
			WTDocument doc=(WTDocument)pbo;
			String filename=(new StringBuilder()).append(doc.getName()).append(".pdf").toString();
			ContentHolder ch=ContentHelper.service.getContents(doc);
			Vector vector = ContentHelper.getContentList(ch);
			if (vector!=null) {
				for (int i=0; i<vector.size(); i++) {
					ContentItem contentitem = (ContentItem)vector.elementAt(i);
					if ((contentitem instanceof ApplicationData) && (contentitem.getRole().equals(ContentRoleType.SECONDARY))) {
						ApplicationData ad=(ApplicationData)contentitem;
						if (filename.equals(ad.getFileName()))
							ContentServerHelper.service.deleteContent(ch, contentitem);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void generatePrintableAttachment(WTDocument doc, File attachFile) {
		Transaction tx=new Transaction();
		try {
			tx.start();
			doc=(WTDocument)PersistenceHelper.manager.lockAndRefresh(doc);
			LOGGER.debug("Create printable attachment ApplicationData");
			ApplicationData applicationdata = ApplicationData.newApplicationData(doc);
			applicationdata.setRole(ContentRoleType.SECONDARY);
			String fname=doc.getName()+".pdf";
			applicationdata.setFileName(fname);
			applicationdata.setDescription(ACAEConstants.ACAE2_AUTO_CREATED_ATTACHMENT);
			InputStream is=new FileInputStream(attachFile);
			applicationdata = ContentServerHelper.service.updateContent(doc, applicationdata, is);
			is.close();
			PersistenceServerHelper.manager.update(doc);
			LOGGER.debug("Update attachment OK.");
			tx.commit();
			tx=null;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (tx!=null)
				tx.rollback();
		}
	}
	
	
	public static boolean isWorkflowHasRole(WfProcess process, String rolestr) {
		try {
			if(process == null || rolestr == null)
				return false;
			
			Role role = Role.toRole(rolestr);
			Team team = (Team) process.getTeamId().getObject();
			Vector rolesVec = team.getRoles();
			if(rolesVec == null || rolesVec.size() ==0)
				return false;
			for (int i = 0; i < rolesVec.size(); i++) {
				Role theRole = (Role)rolesVec.get(i);
				if(theRole.equals(Role.toRole(rolestr)))
					return true;
			}
			
		} catch (Exception wte) {
			wte.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 同步变更产生对象的生命周期的状态
	 * @description TODO
	 * @author cnie
	 * @date 2013-6-8 下午3:03:18
	 * @version 1.0
	 * @param pbo
	 * @param strState
	 * @throws LifeCycleException
	 * @throws WTException
	 */
	public static void sycnChangeItemState(Object pbo,String strState) throws LifeCycleException, WTException{
		State state = State.toState(strState);
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			state = ecn.getLifeCycleState();
			ArrayList<WTObject> wtobjs = ECNHelper.getChangeResultingItem(ecn);
			for(WTObject obj :wtobjs){
				if(obj instanceof LifeCycleManaged){
					LifeCycleManaged lcm = (LifeCycleManaged)obj;
					if(LifeCycleHelper.service.isState(LifeCycleHelper.service.getLifeCycleTemplate(lcm),state ))   //判断当前对象关联的生命周期模版是否存在当前的状态
						continue;
					else{
						LifeCycleManaged afterlcm = LifeCycleHelper.service.setLifeCycleState(lcm, state);
						PersistenceServerHelper.manager.update(afterlcm);
						afterlcm = (LifeCycleManaged) PersistenceHelper.manager.refresh(afterlcm);
					}
				}
			}
		}
		
	}
	
	
	/***
	 * 判断是否存在可视化产生的pdf附件
	 * @description TODO
	 * @author cnie
	 * @date 2013-6-8 下午2:49:45
	 * @version 1.0
	 * @param pbo
	 * @return
	 */
	public static boolean checkPrintableAttachment(Object pbo) {
		boolean check=false;
		try {
			WTChangeOrder2 ecn=(WTChangeOrder2)pbo;
			ArrayList<WTObject> wtobjs = ECNHelper.getChangeResultingItem(ecn);
			for(WTObject wtobj:wtobjs){
				if(wtobj instanceof WTDocument){
					WTDocument doc = (WTDocument)wtobj;
					String filename=(new StringBuilder()).append(doc.getName()).append(".pdf").toString();
					ContentHolder ch=ContentHelper.service.getContents(doc);
					Vector vector = ContentHelper.getContentList(ch);
					if (vector!=null) {
						for (int i=0; i<vector.size(); i++) {
							ContentItem contentitem = (ContentItem)vector.elementAt(i);
							if ((contentitem instanceof ApplicationData) && (contentitem.getRole().equals(ContentRoleType.SECONDARY))) {
								ApplicationData ad=(ApplicationData)contentitem;
								if (filename.equals(ad.getFileName())) {
									check=true;
									break;
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return check;
	}
	
	/**
	 * 得到历史
	 * @description TODO
	 * @author cnie
	 * @date 2013-6-8 下午3:52:32
	 * @version 1.0
	 * @param self
	 * @param obj
	 * @return
	 */
	public static String getHistoryDispatched(ObjectReference self, Object pbo) {
    	String ret = "";
    	HashSet set = new HashSet();
    	try {
    		
    		if(pbo instanceof WTChangeOrder2){
    			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
    			String ecnType = TypeIdentifierHelper.getType(ecn).toExternalForm();
    			ArrayList<WTObject> wtobjs = ECNHelper.getChangeResultingItem(ecn);
    			for(WTObject wtobj :wtobjs){
    				if(wtobj instanceof WTDocument||wtobj instanceof WTPart){
    					WTDocument doc = (WTDocument)wtobj;
    					QueryResult qr = VersionControlHelper.service.allVersionsOf(doc.getMaster(), false);
    					while (qr.hasMoreElements()) {
    						WTDocument verDoc = (WTDocument) qr.nextElement();
    						if(verDoc.equals(doc))
    							continue;
    						else{
    							QueryResult ecnQr = ChangeHelper2.service.getLatestUniqueImplementedChangeOrders(doc);
        						if(ecnQr.hasMoreElements()){
        							WTChangeOrder2 vcEcn = (WTChangeOrder2) ecnQr.nextElement();
        							ArrayList<WfProcess> processes = getAllCompletedWfProcess(vcEcn);
        							if (processes.size() > 0){
        			    				for (int i=0; i<processes.size(); i++) {
        			    					ProcessData processData = processes.get(i).getContext();
        			    					String tmp = (String)(processData.getValue(AcaeConstants.SHOW_DISPATCH_DEPT));
        			    					if (tmp != null && tmp.equals("")) {
        			    						String[] strs = tmp.split(",");
        			    						for (int k = 0; k < strs.length; k++) {
        			    							set.add(strs[k]);
        			    						}
        			    					}
        			    				}
        			    				break;
        			    			}
        						}	
    						}
    						if(set.size()>0)
    							break;
    					}
    					break;
    				}
    			}
    		}
    		
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	Iterator it = set.iterator();
    	while (it.hasNext()) {
    		ret += it.next().toString() + ",";
    	}
    	
    	int endIndex = ret.lastIndexOf(",");
    	if (endIndex != -1){
    		ret = ret.substring(0, endIndex);
    	}
    	return ret;
    }
	
	
	public static ArrayList<WfProcess> getAllCompletedWfProcess(Persistable obj) {
		ArrayList<WfProcess> list=new ArrayList<WfProcess>();
    	try {
    		QueryResult qs=WfEngineHelper.service.getAssociatedProcesses(obj, WfState.CLOSED_COMPLETED, null);
	        if (qs.size()<1)
	            return list;

	        CollationKeyFactory timeKeyFact = new CollationKeyFactory() {
	            public String getCollationString(Object o) {
	                if (!(o instanceof Persistable) || !PersistenceHelper.isPersistent(o))
	                    return "";
	                return ((Persistable) o).getPersistInfo().getModifyStamp().toString();
	            }
	        };
	        Enumeration enProcs = new SortedEnumeration(qs, timeKeyFact, SortedEnumeration.DESCENDING);
	        while (enProcs.hasMoreElements())
	        	list.add((WfProcess)enProcs.nextElement());
	        return list;
    	} catch (WTException wte) {
    		LOGGER.debug("getLatestWfProcess() Exception:"+wte.getMessage());
    		wte.printStackTrace();
    	}
    	return list;
    }
	
	public static void doWorkAfterReviewProcess(ObjectReference self,Object pbo){
		
		if(pbo instanceof WTChangeOrder2){
			WTChangeOrder2 ecn = (WTChangeOrder2)pbo;
			String ecnType = TypeIdentifierHelper.getType(ecn).toExternalForm();
			ArrayList<WTObject> wtobjs = ECNHelper.getChangeResultingItem(ecn);
			if(ecnType.indexOf(ACAEConstants.ACAE2_TYPE_FILE_ECN)>-1){
				WTDocument doc = (WTDocument) wtobjs.get(0);
				NfWorkflowHelper.doWorkAfterReviewProcess(self, doc); //调用一期的代码
			}
		}
		
	}
	
	
	public static void main(String[] args) {
		
	}

}
